package com.supermap.panes;

import com.supermap.Helper;
import com.supermap.data.Enum;
import com.supermap.data.*;
import com.supermap.panes.advance.SettingPane;
import com.supermap.realspace.AnalysisMode;
import com.supermap.realspace.DisplayMode;
import com.supermap.realspace.HypsometricSetting;
import com.supermap.realspace.TerrainLayers;
import com.supermap.ui.Action3D;
import com.supermap.ui.SceneControl;
import com.supermap.ui.Tracking3DListener;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;

public class HypsometricAnalystPane extends SettingPane {
    private SceneControl sceneControl;

    private JComboBox<AnalysisMode> analysisModeCbx;
    private JComboBox<DisplayMode> displayModeCbx;
    private JButton lineColorBtn;
    private JTextField transparencyTxt;
    private JTextField minVisibleValueTxt;
    private JTextField maxVisibleValueTxt;
    private JTextField intervalTxt;

    private HypsometricSetting hypsometricSetting;
    private Tracking3DListener tracking3DListener = tracking3DEvent -> {
        Geometry3D geometry = tracking3DEvent.getGeometry();
        if (sceneControl.getAction() == Action3D.CREATE_POLYGON && geometry instanceof GeoRegion3D) {
            GeoRegion3D geoRegion3D = (GeoRegion3D) geometry;
            if (geoRegion3D.getPartCount() > 0) {
                generateHypsometricSetting(geoRegion3D);
                sceneControl.getScene().getTerrainLayers().setHypsometricSetting(hypsometricSetting);
            }
        }
    };

    public HypsometricAnalystPane(String title, SceneControl sceneControl) {
        super(title, new Object[]{sceneControl});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        sceneControl = (SceneControl) args[0];
    }

    @Override
    protected void initializeCore() {
        this.confirmBtn.setVisible(false);
        super.mainPanel.setLayout(new BorderLayout());

        JToolBar toolBar = new JToolBar();
        super.mainPanel.add(toolBar, BorderLayout.NORTH);

        JButton drawRectBtn = new JButton("绘制");
        toolBar.add(drawRectBtn);
        drawRectBtn.addActionListener(e -> {
            sceneControl.setAction(Action3D.CREATE_POLYGON);
            sceneControl.addTrackingListener(tracking3DListener);
        });

        JButton clearBtn = new JButton("清空");
        toolBar.add(clearBtn);
        clearBtn.addActionListener(e -> clearHypsometricLayer());

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new FlowLayout());
        super.mainPanel.add(centerPanel, BorderLayout.CENTER);

        JPanel parametersPanel = new JPanel();
        parametersPanel.setLayout(new GridBagLayout());
        centerPanel.add(parametersPanel);

        parametersPanel.add(new JLabel("分析模式:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        analysisModeCbx = new JComboBox<>();
        parametersPanel.add(analysisModeCbx, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        analysisModeCbx.removeAll();
        Enum[] analysisModes = AnalysisMode.getEnums(AnalysisMode.class);
        for (Enum analysisMode : analysisModes) {
            analysisModeCbx.addItem((AnalysisMode) analysisMode);
        }

        parametersPanel.add(new JLabel("显示模式:"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        displayModeCbx = new JComboBox<>();
        parametersPanel.add(displayModeCbx, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        displayModeCbx.removeAll();
        Enum[] displayModes = DisplayMode.getEnums(DisplayMode.class);
        for (Enum displayMode : displayModes) {
            displayModeCbx.addItem((DisplayMode) displayMode);
        }

        lineColorBtn = new JButton("线颜色");
        parametersPanel.add(lineColorBtn, new GridBagConstraints(0, 2, 2, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("透明度(%):"), new GridBagConstraints(0, 3, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        transparencyTxt = new JTextField();
        parametersPanel.add(transparencyTxt, new GridBagConstraints(1, 3, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("最小可见高程:"), new GridBagConstraints(0, 4, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        minVisibleValueTxt = new JTextField();
        parametersPanel.add(minVisibleValueTxt, new GridBagConstraints(1, 4, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("最大可见高程:"), new GridBagConstraints(0, 5, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        maxVisibleValueTxt = new JTextField();
        parametersPanel.add(maxVisibleValueTxt, new GridBagConstraints(1, 5, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("等值距:"), new GridBagConstraints(0, 6, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        intervalTxt = new JTextField();
        parametersPanel.add(intervalTxt, new GridBagConstraints(1, 6, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        initializeDefaultValues();
    }

    @Override
    protected void doConfirm() {

    }

    @Override
    protected void doClose() {
        clearHypsometricLayer();
        for (Component component : getComponents()) {
            component.disable();
        }
    }

    private void initializeDefaultValues() {
        analysisModeCbx.setSelectedItem(AnalysisMode.CONTOUR_MAP);
        analysisModeCbx.addItemListener(e -> refreshHypsometricLayer());
        displayModeCbx.setSelectedItem(DisplayMode.FACE_AND_LINE);
        displayModeCbx.addItemListener(e -> refreshHypsometricLayer());
        lineColorBtn.setForeground(Color.BLACK);
        lineColorBtn.setBackground(Color.BLACK);
        lineColorBtn.addActionListener(e -> {
            Color color = JColorChooser.showDialog(sceneControl, "线颜色", lineColorBtn.getForeground());
            if (color != null) {
                lineColorBtn.setForeground(color);
                lineColorBtn.setBackground(color);
            }
            refreshHypsometricLayer();
        });
        transparencyTxt.setText("50");
        transparencyTxt.addActionListener(e -> refreshHypsometricLayer());
        double minVisibleValue = 0;
        double maxVisibleValue = 90;
        TerrainLayers terrainLayers = sceneControl.getScene().getTerrainLayers();
        for (int i = 0; i < terrainLayers.getCount(); i++) {
            Dataset dataset = terrainLayers.get(i).getDataset();
            if (dataset instanceof DatasetGrid) {
                DatasetGrid datasetGrid = (DatasetGrid) dataset;
                minVisibleValue = datasetGrid.getMinValue();
                maxVisibleValue = datasetGrid.getMaxValue();
            }
        }
        minVisibleValueTxt.setText(String.valueOf(minVisibleValue));
        minVisibleValueTxt.addActionListener(e -> refreshHypsometricLayer());
        maxVisibleValueTxt.setText(String.valueOf(maxVisibleValue));
        maxVisibleValueTxt.addActionListener(e -> refreshHypsometricLayer());
        intervalTxt.setText("25");
        intervalTxt.addActionListener(e -> refreshHypsometricLayer());
    }

    private void refreshHypsometricLayer() {
        if (hypsometricSetting == null) {
            generateHypsometricSetting(null);
        }
        Geometry coverageRegion = hypsometricSetting.getCoverageRegion();
        clearHypsometricLayer();
        generateHypsometricSetting(coverageRegion);
        TerrainLayers terrainLayers = sceneControl.getScene().getTerrainLayers();
        if (coverageRegion != null) {
            terrainLayers.setHypsometricSetting(hypsometricSetting);
        }
    }

    private void generateHypsometricSetting(Geometry geometry) {
        hypsometricSetting = new HypsometricSetting();
        hypsometricSetting.setAnalysisMode((AnalysisMode) analysisModeCbx.getSelectedItem());
        hypsometricSetting.setDisplayMode((DisplayMode) displayModeCbx.getSelectedItem());
        hypsometricSetting.setLineColor(lineColorBtn.getForeground());
        double maxVisibleValue = Double.parseDouble(maxVisibleValueTxt.getText());
        double minVisibleValue = Double.parseDouble(minVisibleValueTxt.getText());
        double stepValue = (maxVisibleValue - minVisibleValue) / 3;
        HashMap<Double, Color> colorTable = new HashMap<>();
        colorTable.put(minVisibleValue, Color.BLUE);
        colorTable.put(minVisibleValue + stepValue, Color.GREEN);
        colorTable.put(maxVisibleValue - stepValue, Color.RED);
        hypsometricSetting.setColorDictTable(colorTable);
        hypsometricSetting.setInterval(Double.parseDouble(intervalTxt.getText()));
        hypsometricSetting.setOpacity(100 - Double.parseDouble(transparencyTxt.getText()));
        hypsometricSetting.setMinVisibleAltitude(Double.parseDouble(minVisibleValueTxt.getText()));
        hypsometricSetting.setMaxVisibleAltitude(Double.parseDouble(maxVisibleValueTxt.getText()));
        if (geometry != null) {
            hypsometricSetting.setCoverageRegion(geometry);
        }
    }

    private void clearHypsometricLayer() {
        if (hypsometricSetting != null) {
            hypsometricSetting.setDisplayMode(DisplayMode.NONE);
        }
        TerrainLayers terrainLayers = sceneControl.getScene().getTerrainLayers();
        terrainLayers.setHypsometricSetting(hypsometricSetting);
        hypsometricSetting = null;
        sceneControl.setAction(Action3D.PAN);
        sceneControl.removeTrackingListener(tracking3DListener);
    }
}
